package top.hidoctor.auscultation.utils;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.media.AudioTrack;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;

import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import top.hidoctor.auscultation.App;
import top.hidoctor.auscultation.feature.activity.DeviceActivity;

public class BlueToothUtils {

    private static BlueToothUtils utils = null;

    //  用户发送指令的操作
    private BluetoothGattCharacteristic writeBluetoothGattCharacteristic;

    //  用于开启通知的操作
    private BluetoothGattCharacteristic notificationBluetoothGattCharacteristic;


    //  服务和特征值
    private UUID write_UUID_service;
    private UUID write_UUID_chara;

    private UUID read_UUID_service;
    private UUID read_UUID_chara;

    private UUID notify_UUID_service;
    private UUID notify_UUID_chara;

    private UUID indicate_UUID_service;
    private UUID indicate_UUID_chara;
    private AudioTrack tracker;
    private int currentMtu = 0;

    private BlueToothHandle blueToothHandle = null;
    private boolean isSetMtu;
    private static BluetoothDevice device;
    private static BluetoothGatt bluetoothGatt;
    private Context context;
    private BluetoothAdapter mBtAdapter;


    public static BluetoothGatt getBluetoothGatt() {
        return bluetoothGatt;
    }

    public static BluetoothDevice getDevice() {
        return device;
    }


    public void setSetMtu(boolean setMtu) {
        isSetMtu = setMtu;
    }


    public void setBlueToothHandle(BlueToothHandle blueToothHandle) {
        this.blueToothHandle = blueToothHandle;
    }


    public static BlueToothUtils getBlueToothUtils() {
        if (utils == null) {
            utils = new BlueToothUtils();
        }
        return utils;
    }


    public interface BlueToothHandle {
        void getCharacteristicChanged(byte[] data);

        void stateDisconnected();

        void stateDisconnecting();

        void stateConnected();

        void stateConnecting();

        void characteristicWrite(int status);

        void startWrite();
    }


    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public BluetoothGatt connect(BluetoothDevice device, Context context) {
        this.context = context;
        this.device = device;
        bluetoothGatt = device.connectGatt(context, false, bluetoothGattCallback);
        return bluetoothGatt;
    }

    private static BluetoothManager mBluetoothManager;

    /**
     * 断开蓝牙
     */
    @SuppressLint("NewApi")
    public void off() {
        if (bluetoothGatt != null) {
            // 隐式关闭蓝牙
            //通过BluetoothManager来获取BluetoothAdapter
            mBluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
            // 一个Android系统只有一个BluetoothAdapter ，通过BluetoothManager 来获取
            mBtAdapter = mBluetoothManager.getAdapter();
//            // 打开蓝牙
//            mBtAdapter.enable();
            // 关闭蓝牙
            mBtAdapter.disable();
            bluetoothGatt.disconnect();
            bluetoothGatt.close();
            currentMtu = 0;
            isSetMtu = false;
            device = null;
        }
    }

    BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
        @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            Log.e("TAG", "onConnectionStateChange: " + newState);
            if (newState == BluetoothProfile.STATE_CONNECTED) {//连接成功
                if (isSetMtu && currentMtu != 247) {
                    bluetoothGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);
                    bluetoothGatt.requestMtu(247);
                }
                // 将会回调 本类中的 onServicesDiscovered() 这个方法
                blueToothHandle.stateConnected();
            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {//连接断开
                Log.e("TAG", "断开连接");
                blueToothHandle.stateDisconnected();
                bluetoothGatt.close();
            } else if (newState == BluetoothProfile.STATE_CONNECTING) {//正在连接
                blueToothHandle.stateConnecting();
            } else if (newState == BluetoothProfile.STATE_DISCONNECTING) {//正则断开
                blueToothHandle.stateDisconnecting();
            }

        }

        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            //发现服务回调
            if (status == BluetoothGatt.GATT_SUCCESS) {
                Log.e("TAG", "发现服务：status=" + status);
                initServiceAndChara();
            }
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);
            //写数据成功
//            if (status == BluetoothGatt.GATT_SUCCESS) {
////                mHandler.sendEmptyMessage(WRITE_SUC);
//            } else {
////                mHandler.sendEmptyMessage(WRITE_FAIL);
//            }
            blueToothHandle.characteristicWrite(status);
        }

        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
            super.onCharacteristicChanged(gatt, characteristic);
            blueToothHandle.getCharacteristicChanged(characteristic.getValue());
        }

        @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorWrite(gatt, descriptor, status);
            //写特征值成功回调
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
            //读取特征值结果回调
        }

        @Override
        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorRead(gatt, descriptor, status);
            //读取描述符结果回调
        }

        @Override
        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
            super.onReliableWriteCompleted(gatt, status);
            //可靠的写事务完成回调
        }

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
            super.onReadRemoteRssi(gatt, rssi, status);
            //设备信号强度回调
        }

        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
        @Override
        public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
            super.onMtuChanged(gatt, mtu, status);
            //MTU改变回调
            if (status == BluetoothGatt.GATT_SUCCESS) {
                currentMtu = mtu;
                bluetoothGatt.discoverServices();

                Log.e("TAG", "onMtuChanged: 设置成功" + mtu);
            } else {
                Log.e("TAG", "onMtuChanged: 设置失败" + mtu);
            }
        }
    };

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    private void initServiceAndChara() {

        List<BluetoothGattService> bluetoothGattServices = bluetoothGatt.getServices();

        for (BluetoothGattService bluetoothGattService : bluetoothGattServices) {
            List<BluetoothGattCharacteristic> characteristics = bluetoothGattService.getCharacteristics();
            for (BluetoothGattCharacteristic characteristic : characteristics) {
                int charaProp = characteristic.getProperties();
                if ((charaProp & BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
                    read_UUID_chara = characteristic.getUuid();
                    read_UUID_service = bluetoothGattService.getUuid();
                    Log.e("TAG", "read_chara=" + read_UUID_chara + "----read_service=" + read_UUID_service);
                }
                if ((charaProp & BluetoothGattCharacteristic.PROPERTY_INDICATE) > 0) {
                    indicate_UUID_chara = characteristic.getUuid();
                    indicate_UUID_service = bluetoothGattService.getUuid();
                    Log.e("TAG", "indicate_chara=" + indicate_UUID_chara + "----indicate_service=" + indicate_UUID_service);
                }
                if ((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
                    write_UUID_chara = characteristic.getUuid();
                    write_UUID_service = bluetoothGattService.getUuid();
                    Log.e("TAG", "write_chara=" + write_UUID_chara + "----write_service=" + write_UUID_service);
                }
                if ((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0) {
                    write_UUID_chara = characteristic.getUuid();
                    write_UUID_service = bluetoothGattService.getUuid();
                    Log.e("TAG", "write_chara=" + write_UUID_chara + "----write_service=" + write_UUID_service);
                    //  写入服务
                    BluetoothGattService service = bluetoothGatt.getService(write_UUID_service);
                    writeBluetoothGattCharacteristic = service.getCharacteristic(write_UUID_chara);

                    //  发送指令
//                    sendBleData("*".getBytes());
                    blueToothHandle.startWrite();

                }
                if ((charaProp & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                    notify_UUID_chara = characteristic.getUuid();
                    notify_UUID_service = bluetoothGattService.getUuid();
                    Log.e("TAG", "notify_chara=" + notify_UUID_chara + "----notify_service=" + notify_UUID_service);

                    //  初始化通知服务
                    BluetoothGattService service = bluetoothGatt.getService(notify_UUID_service);
                    notificationBluetoothGattCharacteristic = service.getCharacteristic(notify_UUID_chara);

                    //  开启通知
                    bluetoothGatt.setCharacteristicNotification(notificationBluetoothGattCharacteristic, true);

                    for (BluetoothGattDescriptor dp : characteristic.getDescriptors()) {
                        dp.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                        bluetoothGatt.writeDescriptor(dp);
                    }
                }
            }
        }
    }


    /**
     * 发送数据给蓝牙
     *
     * @param data 数据byte[]
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    public void write(String data) {
        if (writeBluetoothGattCharacteristic != null) {
            writeBluetoothGattCharacteristic.setValue(data.getBytes());
            bluetoothGatt.writeCharacteristic(writeBluetoothGattCharacteristic);
        }
    }
}

